home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc Source Code / UI / MenuBar.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-22  |  21.9 KB  |  902 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        MenuBar.cpp
  3.  
  4.     Contains:    Implementation of ODMenuBar
  5.  
  6.     Owned by:    Richard Rodseth
  7.  
  8.     Copyright:    © 1994 - 1995 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.         <27>    10/23/95    RR        # 1291688 Synch with menu manager when
  13.                                     adding & removing menus, if this menu bar
  14.                                     is the current menu bar
  15.         <26>     10/8/95    TJ        Fixes Recomended by Refball
  16.         <25>     9/12/95    eeh        1283557: use SetErrorCode
  17.         <24>     8/21/95    RR         #1271358 GetMenuAndItem throws
  18.                                     kODErrInvalidCommandID. EnableCommand etc.
  19.                                     suppress this error and fail silently
  20.         <23>     8/16/95    NP        1274946: ErrorDef.idl problems. Add include
  21.                                     file.
  22.         <22>     8/15/95    RR        #1276683 remove extra new ODPrivMenuInfo.
  23.         <21>      8/3/95    RR        #1257260: Collapse B classes. Remove
  24.                                     somInit methods. Don't call IsInitialized
  25.                                     or SubclassResponsibility
  26.         <20>     7/25/95    VL        1270320: Delete foundMenu in RemoveMenu.
  27.                                     Delete elements in _fOtherMenus before
  28.                                     deleting it.
  29.         <19>     7/25/95    eeh        1259218: remove assert in SetItemString
  30.         <18>      6/8/95    RR        #1257260 Collapse base classes. #1214898
  31.                                     StdTypes.r -> ODTypes.r
  32.         <17>     5/26/95    RR        #1251403: Multithreading naming support
  33.         <16>     5/17/95    RR        #1250135/1250137/1250143 Getters increment
  34.                                     refcount
  35.         <15>     4/28/95    RR        1211085 Remove 5$ comments
  36.         <14>     4/13/95    RR        # 1216618 Added ODVolatile, #1220325
  37.                                     Removed private error code
  38.         <13>      4/7/95    RR        #1216618 Added SOM_TRY etc.
  39.         <12>      4/6/95    RR        #1211085 Remove 5$ comments
  40.         <11>      4/4/95    RR        # 1197749 Get/Set ItemString deal with
  41.                                     script code
  42.         <10>     3/22/95    RR        #1197749, 1194296 Set script code in
  43.                                     SetItemString
  44.          <9>     1/23/95    RR        # 1212896 Added EnableAll and DisableAll
  45.          <8>     1/12/95    jpa        Don't use obsolete Toolbox names [1211211]
  46.          <7>     9/29/94    RA        1189812: Mods for 68K build.
  47.          <6>     8/25/94    RR        Implemented IsValid. Added private
  48.                                     SetGeneration/GetGeneration
  49.          <5>     8/15/94    JBS        1181023:  return kODTrue in IsValid
  50.          <4>     8/15/94    CG        #1181023:  Added new IsValid API.  It is
  51.                                     not implemented yet.
  52.          <3>     7/19/94    eeh        fix to ODMenuBarCopy
  53.          <2>      7/6/94    RR        Implemented SetItemString and GetItemString
  54.          <1>     6/23/94    RR        first checked in
  55.  
  56.     To Do:
  57. */
  58.  
  59.  
  60. #define ODMenuBar_Class_Source
  61. #define VARIABLE_MACROS
  62. #include <MenuBar.xih>
  63.  
  64. #ifndef _PLFMDEF_
  65. #include "PlfmDef.h"
  66. #endif
  67.  
  68. #ifndef SOM_ODSession_xh
  69. #include <ODSessn.xh>
  70. #endif
  71.  
  72. #ifndef _ODUTILS_
  73. #include "ODUtils.h"
  74. #endif
  75.  
  76. #ifndef SOM_ODWindowState_xh
  77. #include <WinStat.xh>
  78. #endif
  79.  
  80. #ifndef _ORDCOLL_
  81. #include "OrdColl.h"
  82. #endif
  83.  
  84. #ifndef _CMDTABLE_
  85. #include "CmdTable.h"
  86. #endif
  87.  
  88. #ifndef _EXCEPT_
  89. #include "Except.h"
  90. #endif
  91.  
  92. #ifndef _ITEXT_
  93. #include "IText.h"
  94. #endif
  95.  
  96. #ifndef _ODDEBUG_
  97. #include "ODDebug.h"    // Adkins -- added
  98. #endif
  99.  
  100. #ifndef _TEMPOBJ_
  101. #include "TempObj.h"
  102. #endif
  103.  
  104. #ifndef _UTILERRS_
  105. #include "UtilErrs.h"
  106. #endif
  107.  
  108. #pragma segment ODMenuBar
  109.  
  110. #include "MenuBarB.cpp"    // Platform-independent methods, if any
  111.  
  112. //=====================================================================================
  113. // Constants
  114. //=====================================================================================
  115. #define kSyntheticMask    0x0F000000
  116. #define kMenuIDMask        0x00FFFF00
  117. #define kMenuIDShift    8
  118. #define kMenuItemMask    0x000000FF
  119.  
  120.  
  121. class ODPrivMenuInfo
  122. {
  123. public:
  124.     ODPrivMenuInfo(ODMenuID menuID, ODPlatformMenu menu,  
  125.                 ODPart* part, ODSShort position);
  126.     ~ODPrivMenuInfo();
  127.  
  128.     ODMenuID        fMenuID;
  129.     ODPlatformMenu  fMenu;
  130.     ODPart*            fPart;
  131.     ODSShort        fPosition;
  132. };
  133.  
  134. ODPrivMenuInfo::ODPrivMenuInfo( ODMenuID menuID, ODPlatformMenu menu, 
  135.                          ODPart* part, ODSShort position)
  136. {
  137.     fMenuID = menuID;
  138.     fMenu = menu;
  139.     fPart = part;
  140.     fPosition = position;
  141. }
  142.  
  143. ODPrivMenuInfo::~ODPrivMenuInfo()
  144. {
  145. }
  146.  
  147. //=====================================================================================
  148. // Class ODMenuBar
  149. //=====================================================================================
  150.  
  151.  
  152. SOM_Scope void  SOMLINK ODMenuBarInitMenuBar(ODMenuBar *somSelf, Environment *ev,
  153.         ODSession* session,
  154.         ODPlatformMenuBar menuBar)
  155. {
  156.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  157.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarInitMenuBar");
  158.  
  159.     SOM_TRY
  160.             
  161.         /* Moved from somInit. SOM itself sets fields to zero
  162.         _fSession = kODNULL;
  163.         _fSystemMenus = kODNULL;
  164.         _fCommandTable = kODNULL;
  165.         _fOtherMenus = kODNULL;
  166.         _fGeneration = 0;
  167.         */
  168.         
  169.         somSelf->InitRefCntObject(ev); 
  170.     
  171.         _fSession = session;
  172.         _fSystemMenus = menuBar;
  173.         
  174.     SOM_CATCH_ALL
  175.     SOM_ENDTRY
  176. }
  177.  
  178. SOM_Scope void  SOMLINK ODMenuBarAddSubMenu(ODMenuBar *somSelf, Environment *ev,
  179.         ODMenuID menuID,
  180.         ODPlatformMenu menu,
  181.         ODPart* part)
  182. {
  183.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  184.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarAddSubMenu");
  185.   
  186.       OrderedCollection* otherMenus = kODNULL; ODVolatile(otherMenus);
  187.     ODPrivMenuInfo* info = kODNULL; ODVolatile(info);
  188.       
  189.     SOM_TRY
  190.  
  191.         if (_fOtherMenus == kODNULL)
  192.         {
  193.             otherMenus = new OrderedCollection;
  194.             _fOtherMenus = otherMenus;
  195.         }
  196.         info = new ODPrivMenuInfo(menuID, menu,part, hierMenu);
  197.         _fOtherMenus->AddLast((ElementType) info);
  198.  
  199.         // if this is the current menu bar, we should also tell the Menu Manager
  200.         TempODMenuBar currentMenuBar = _fSession->GetWindowState(ev)->AcquireCurrentMenuBar(ev);
  201.         if (ODObjectsAreEqual(ev, currentMenuBar, somSelf))
  202.         {
  203.             ::InsertMenu(menu, hierMenu);
  204.             ::InvalMenuBar();
  205.         }
  206.  
  207.     SOM_CATCH_ALL
  208.     
  209.         ODDeleteObject(otherMenus);
  210.         ODDeleteObject(info);
  211.         
  212.     SOM_ENDTRY
  213.  
  214. }
  215.  
  216. SOM_Scope void  SOMLINK ODMenuBarRegisterCommand(ODMenuBar *somSelf, Environment *ev,
  217.         ODCommandID command,
  218.         ODMenuID menu,
  219.         ODMenuItemID menuItem)
  220. {
  221.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  222.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarRegisterCommand");
  223.     
  224.     CommandTable* table = kODNULL; ODVolatile(table);
  225.     
  226.     SOM_TRY
  227.  
  228.         if (_fCommandTable == kODNULL)
  229.         {
  230.             table = new CommandTable;
  231.             _fCommandTable = table;
  232.         }
  233.         _fCommandTable->RegisterCommand(command, menu, menuItem);
  234.     
  235.     SOM_CATCH_ALL
  236.     
  237.         ODDeleteObject(table);
  238.         
  239.     SOM_ENDTRY
  240. }
  241.  
  242. SOM_Scope void  SOMLINK ODMenuBarUnregisterCommand(ODMenuBar *somSelf, Environment *ev,
  243.         ODCommandID command)
  244. {
  245.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  246.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarUnregisterCommand");
  247.  
  248.     SOM_TRY
  249.     
  250.         if (_fCommandTable)
  251.             _fCommandTable->UnregisterCommand(command);
  252.         
  253.     SOM_CATCH_ALL
  254.     SOM_ENDTRY
  255. }
  256.  
  257. SOM_Scope void  SOMLINK ODMenuBarUnregisterAll(ODMenuBar *somSelf, Environment *ev)
  258. {
  259.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  260.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarUnregisterAll");
  261.  
  262.     SOM_TRY
  263.     
  264.         if (_fCommandTable)
  265.             _fCommandTable->UnregisterAll();
  266.  
  267.     SOM_CATCH_ALL
  268.     SOM_ENDTRY
  269. }
  270.  
  271.  
  272. SOM_Scope ODBoolean  SOMLINK ODMenuBarIsCommandRegistered(ODMenuBar *somSelf, Environment *ev,
  273.         ODCommandID command)
  274. {
  275.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  276.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarIsCommandRegistered");
  277.     
  278.     ODBoolean isRegistered = kODFalse;
  279.  
  280.     SOM_TRY
  281.     
  282.         if (_fCommandTable)
  283.             isRegistered = _fCommandTable->IsCommandRegistered(command);
  284.  
  285.     SOM_CATCH_ALL
  286.     SOM_ENDTRY
  287.     
  288.     return isRegistered;
  289. }
  290.  
  291. SOM_Scope ODBoolean  SOMLINK ODMenuBarIsCommandSynthetic(ODMenuBar *somSelf, Environment *ev,
  292.         ODCommandID command)
  293. {
  294.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  295.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarIsCommandSynthetic");
  296.  
  297.     return (command&kSyntheticMask) == kSyntheticMask;
  298. }
  299.  
  300. SOM_Scope ODCommandID  SOMLINK ODMenuBarGetCommand(ODMenuBar *somSelf, Environment *ev,
  301.         ODMenuID menu,
  302.         ODMenuItemID menuItem)
  303. {
  304.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  305.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarGetCommand");
  306.  
  307.     ODCommandID command = kNoCommand;
  308.     
  309.     SOM_TRY
  310.     
  311.         if (_fCommandTable)
  312.             command = _fCommandTable->GetCommand(menu, menuItem);
  313.             
  314.         if (command == kNoCommand)
  315.             // No command in table, so synthesize one:
  316.             command = kSyntheticMask | ((long)menu<<kMenuIDShift) | (menuItem & kMenuItemMask);
  317.  
  318.     SOM_CATCH_ALL
  319.     SOM_ENDTRY
  320.         
  321.     return command;
  322. }
  323.  
  324. SOM_Scope void  SOMLINK ODMenuBarGetMenuAndItem(ODMenuBar *somSelf, Environment *ev,
  325.         ODCommandID command,
  326.         ODMenuID* menu,
  327.         ODMenuItemID* menuItem)
  328. {
  329.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  330.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarGetMenuAndItem");
  331.  
  332.     ODBoolean found = kODFalse;
  333.     
  334.     SOM_TRY
  335.     
  336.         if (somSelf->IsCommandSynthetic(ev, command)) 
  337.         {    
  338.             *menu = (ODMenuID) ((command & kMenuIDMask) >>kMenuIDShift);
  339.             *menuItem = (ODMenuItemID) (command & kMenuItemMask);
  340.             found = kODTrue;
  341.         }
  342.         else if (_fCommandTable)
  343.         {
  344.             found = _fCommandTable->GetMenuAndItem(command, *menu, *menuItem);
  345.         }
  346.         if (!found)
  347.             THROW(kODErrInvalidCommandID); 
  348.  
  349.     SOM_CATCH_ALL
  350.     SOM_ENDTRY
  351. }
  352.  
  353. SOM_Scope void  SOMLINK ODMenuBarEnableCommand(ODMenuBar *somSelf, Environment *ev,
  354.         ODCommandID cmdNumber,
  355.         ODBoolean enable)
  356. {
  357.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  358.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarEnableCommand");
  359.  
  360.     SOM_TRY
  361.  
  362.         ODMenuID menuID;
  363.         ODMenuItemID item;
  364.         somSelf->GetMenuAndItem( ev, cmdNumber, &menuID, &item ) ; // THROWS
  365.         ODPlatformMenu macMenu = somSelf->GetMenu( ev, menuID ) ;
  366.         if (macMenu)
  367.         {
  368.             if (enable)
  369.                 EnableItem(macMenu, item) ;
  370.             else
  371.                 DisableItem(macMenu, item) ;
  372.         }
  373.             
  374.     SOM_CATCH_ALL
  375.     
  376.         SetErrorCode(kODNoError);
  377.         
  378.     SOM_ENDTRY
  379. }
  380.  
  381. SOM_Scope void  SOMLINK ODMenuBarCheckCommand(ODMenuBar *somSelf, Environment *ev,
  382.         ODCommandID cmdNumber,
  383.         ODBoolean check)
  384. {
  385.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  386.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarCheckCommand");
  387.     
  388.     SOM_TRY
  389.  
  390.         ODMenuID menuID;
  391.         ODMenuItemID item;
  392.         somSelf->GetMenuAndItem( ev, cmdNumber, &menuID, &item ) ;
  393.         ODPlatformMenu macMenu = somSelf->GetMenu( ev, menuID ) ;
  394.         if (macMenu)
  395.             CheckItem(macMenu, item, check); 
  396.  
  397.     SOM_CATCH_ALL
  398.     
  399.         SetErrorCode(kODNoError);
  400.     
  401.     SOM_ENDTRY
  402.  
  403. }
  404.  
  405. SOM_Scope void  SOMLINK ODMenuBarEnableAndCheckCommand(ODMenuBar *somSelf, Environment *ev,
  406.         ODCommandID cmdNumber,
  407.         ODBoolean enable,
  408.         ODBoolean check)
  409. {
  410.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  411.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarEnableAndCheckCommand");
  412.  
  413.     SOM_TRY
  414.  
  415.         ODMenuID menuID;
  416.         ODMenuItemID item;
  417.         somSelf->GetMenuAndItem( ev, cmdNumber, &menuID, &item ) ;
  418.         ODPlatformMenu macMenu = somSelf->GetMenu( ev, menuID ) ;
  419.         if (macMenu)
  420.         {
  421.         if ( enable )
  422.             EnableItem(macMenu, item) ;
  423.         else
  424.             DisableItem(macMenu, item) ;
  425.         CheckItem(macMenu, item, check); 
  426.         }
  427.  
  428.     SOM_CATCH_ALL
  429.  
  430.         SetErrorCode(kODNoError);
  431.  
  432.     SOM_ENDTRY
  433. }
  434.  
  435. SOM_Scope void  SOMLINK ODMenuBarSetItemString(ODMenuBar *somSelf, Environment *ev,
  436.         ODCommandID cmdNumber,
  437.         ODIText* itemString)
  438. {
  439.     const ODSShort    kUseSpecificScript = 0x1c;
  440.  
  441.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  442.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarSetItemString");
  443.     
  444.     SOM_TRY
  445.  
  446.         ODMenuID menuID;
  447.         ODMenuItemID item;
  448.         somSelf->GetMenuAndItem( ev, cmdNumber, &menuID, &item ) ;
  449.         ODPlatformMenu macMenu = somSelf->GetMenu( ev, menuID ) ;
  450.         if( macMenu != kODNULL ) 
  451.         {
  452.             StringPtr s = GetPStringFromIText(itemString);
  453.             SetMenuItemText(macMenu, item, s); 
  454.             ODDisposePtr(s);
  455.         
  456.             short scriptID = GetITextScriptCode(itemString);
  457.             ODSLong    savedSMFontForceFlag = GetScriptManagerVariable(smFontForce);
  458.             SetScriptManagerVariable(smFontForce, false);
  459.         
  460.             if (scriptID != FontToScript(GetAppFont()))
  461.             {
  462.                 SetItemCmd(macMenu, item, kUseSpecificScript);
  463.                 SetItemIcon(macMenu, item, scriptID);
  464.             }
  465.             
  466.             SetScriptManagerVariable(smFontForce, savedSMFontForceFlag);
  467.         }
  468.  
  469.     SOM_CATCH_ALL
  470.  
  471.         SetErrorCode(kODNoError);
  472.  
  473.     SOM_ENDTRY
  474. }
  475.  
  476. SOM_Scope void  SOMLINK ODMenuBarGetItemString(ODMenuBar *somSelf, Environment *ev,
  477.         ODCommandID cmdNumber,
  478.         ODIText* itemString)
  479. {
  480.     const ODSShort    kUseSpecificScript = 0x1c;
  481.  
  482.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  483.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarGetItemString");
  484.     
  485.     SOM_TRY
  486.  
  487.         ODMenuID menuID;
  488.         ODMenuItemID item;
  489.         somSelf->GetMenuAndItem( ev, cmdNumber, &menuID, &item ) ;
  490.         ODPlatformMenu macMenu = somSelf->GetMenu( ev, menuID ) ;
  491.         if (macMenu)
  492.         {
  493.             if (itemString)    
  494.             {
  495.                 itemString->format = kODTraditionalMacText;
  496.                 itemString->text._buffer = kODNULL;
  497.             }
  498.             
  499.             Str255 s;
  500.             GetMenuItemText(macMenu, item, s); 
  501.             SetITextString(itemString, s);
  502.             
  503.             // Is this correct?
  504.             short cmd;
  505.             short scriptID = smSystemScript;
  506.             ODSLong    savedSMFontForceFlag = GetScriptManagerVariable(smFontForce);
  507.             SetScriptManagerVariable(smFontForce, false);
  508.             GetItemCmd (macMenu, item, &cmd);
  509.             if (cmd == kUseSpecificScript)
  510.             {
  511.                 GetItemIcon (macMenu, item, &scriptID);
  512.             }
  513.             SetITextScriptCode(itemString, scriptID);
  514.             SetITextLangCode(itemString, langEnglish);
  515.             SetScriptManagerVariable(smFontForce, savedSMFontForceFlag);
  516.         }
  517.  
  518.     SOM_CATCH_ALL
  519.     SOM_ENDTRY
  520. }
  521.  
  522. SOM_Scope void  SOMLINK ODMenuBarSetCommandTable(ODMenuBar *somSelf, Environment *ev,
  523.         CommandTable* table)
  524. {
  525.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  526.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarSetCommandTable");
  527.  
  528.     _fCommandTable = table;
  529. }
  530.  
  531. SOM_Scope void  SOMLINK ODMenuBarDisableAll(ODMenuBar *somSelf, Environment *ev)
  532. {
  533.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  534.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarDisableAll");
  535.  
  536.     SOM_TRY
  537.     
  538.         if (_fOtherMenus)
  539.         {
  540.             ODPlatformMenu platformMenu = kODNULL;
  541.             OrderedCollectionIterator iter(_fOtherMenus);
  542.             for (ODPrivMenuInfo* menuInfo = (ODPrivMenuInfo*) iter.First();
  543.                 iter.IsNotComplete();
  544.                 menuInfo = (ODPrivMenuInfo*) iter.Next())
  545.             {
  546.                 platformMenu = menuInfo->fMenu;
  547.                 DisableItem(platformMenu,0);
  548.             }
  549.         }
  550.         
  551.     SOM_CATCH_ALL
  552.     SOM_ENDTRY
  553. }
  554.  
  555. SOM_Scope void  SOMLINK ODMenuBarEnableAll(ODMenuBar *somSelf, Environment *ev)
  556. {
  557.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  558.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarEnableAll");
  559.  
  560.     SOM_TRY
  561.     
  562.         if (_fOtherMenus)
  563.         {
  564.             ODPlatformMenu platformMenu = kODNULL;
  565.             OrderedCollectionIterator iter(_fOtherMenus);
  566.             for (ODPrivMenuInfo* menuInfo = (ODPrivMenuInfo*) iter.First();
  567.                 iter.IsNotComplete();
  568.                 menuInfo = (ODPrivMenuInfo*) iter.Next())
  569.             {
  570.                 platformMenu = menuInfo->fMenu;
  571.                 EnableItem(platformMenu,0);
  572.             }
  573.         }
  574.     SOM_CATCH_ALL
  575.     SOM_ENDTRY
  576. }
  577.  
  578. SOM_Scope void  SOMLINK ODMenuBarsomUninit(ODMenuBar *somSelf)
  579. {
  580.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  581.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarsomUninit");
  582.  
  583.     ODDeleteObject(_fCommandTable);
  584.  
  585.     if (_fOtherMenus)
  586.     {
  587.         TRY
  588.             OrderedCollectionIterator* iter = _fOtherMenus->CreateIterator();
  589.             for (ElementType t = iter->First(); iter->IsNotComplete(); t = iter->Next())
  590.             {
  591.                 ODDeleteObject(t);
  592.             }
  593.             ODDeleteObject(iter);
  594.             ODDeleteObject(_fOtherMenus);
  595.         CATCH_ALL
  596.             // Ignore any exceptions
  597.         ENDTRY
  598.     }
  599. }
  600.  
  601. SOM_Scope ODSize  SOMLINK ODMenuBarPurge(ODMenuBar *somSelf, Environment *ev,
  602.         ODSize size)
  603. {
  604.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  605.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarPurge");
  606.  
  607.     ODSize purgeSize = 0;
  608.     
  609.     SOM_TRY
  610.     
  611.         purgeSize = parent_Purge(somSelf, ev, size);
  612.         
  613.     SOM_CATCH_ALL
  614.         WARN("Error %ld trying to purge in ODMenuBarPurge",ErrorCode());
  615.         SetErrorCode(kODNoError);        // dh - Eat the exception; Purge should not 
  616.                                         // propagate it because clients function
  617.                                         // fine whether memory was purged or not.
  618.     SOM_ENDTRY
  619.     
  620.     return purgeSize;
  621. }
  622.  
  623. SOM_Scope void  SOMLINK ODMenuBarRelease(ODMenuBar *somSelf, Environment *ev)
  624. {
  625.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  626.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarRelease");
  627.     
  628.     SOM_TRY
  629.  
  630.         parent_Release(somSelf,ev);
  631.         if (somSelf->GetRefCount(ev) == 0) 
  632.             somSelf->somFree(); 
  633.         
  634.     SOM_CATCH_ALL
  635.     SOM_ENDTRY    
  636. }
  637.  
  638. SOM_Scope void  SOMLINK ODMenuBarDisplay(ODMenuBar *somSelf, Environment *ev)
  639. {
  640.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  641.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarDisplay");
  642.  
  643.     SOM_TRY
  644.  
  645.         if (_fSystemMenus) 
  646.         {
  647.             ClearMenuBar();
  648.             SetMenuBar(_fSystemMenus);
  649.         }
  650.         if (_fOtherMenus)
  651.         {
  652.             OrderedCollectionIterator iter(_fOtherMenus);
  653.             for (ODPrivMenuInfo* menu = (ODPrivMenuInfo*) iter.First();
  654.                 iter.IsNotComplete();
  655.                 menu = (ODPrivMenuInfo*) iter.Next())
  656.             {
  657.                 InsertMenu(menu->fMenu,menu->fPosition);
  658.             }
  659.         }
  660.         InvalMenuBar();
  661.         
  662.         _fSession->GetWindowState(ev)->SetCurrentMenuBar(ev,somSelf);
  663.         
  664.     SOM_CATCH_ALL
  665.     SOM_ENDTRY    
  666. }
  667.  
  668. SOM_Scope void  SOMLINK ODMenuBarAddMenuLast(ODMenuBar *somSelf, Environment *ev,
  669.         ODMenuID menuID,
  670.         ODPlatformMenu menu,
  671.         ODPart* part)
  672. {
  673.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  674.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarAddMenuLast");
  675.  
  676.       OrderedCollection* otherMenus = kODNULL; ODVolatile(otherMenus);
  677.     ODPrivMenuInfo* info = kODNULL; ODVolatile(info);
  678.     
  679.     SOM_TRY
  680.     
  681.         if (_fOtherMenus == kODNULL)
  682.         {
  683.             otherMenus = new OrderedCollection;
  684.             _fOtherMenus = otherMenus;
  685.         }
  686.         info = new ODPrivMenuInfo(menuID, menu,part, 0);
  687.         _fOtherMenus->AddLast((ElementType) info);
  688.  
  689.         // if this is the current menu bar, we should also tell the Menu Manager
  690.         TempODMenuBar currentMenuBar = _fSession->GetWindowState(ev)->AcquireCurrentMenuBar(ev);
  691.         if (ODObjectsAreEqual(ev, currentMenuBar, somSelf))
  692.         {
  693.             ::InsertMenu(menu, 0);
  694.             ::InvalMenuBar();
  695.         }
  696.  
  697.     SOM_CATCH_ALL
  698.     
  699.         ODDeleteObject(otherMenus);
  700.         ODDeleteObject(info);
  701.         
  702.     SOM_ENDTRY    
  703. }
  704.  
  705. SOM_Scope void  SOMLINK ODMenuBarAddMenuBefore(ODMenuBar *somSelf, Environment *ev,
  706.         ODMenuID menuID,
  707.         ODPlatformMenu menu,
  708.         ODPart* part,
  709.         ODMenuID beforeID)
  710. {
  711.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  712.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarAddMenuBefore");
  713.  
  714.       OrderedCollection* otherMenus = kODNULL; ODVolatile(otherMenus);
  715.     ODPrivMenuInfo* info = kODNULL; ODVolatile(info);
  716.  
  717.     SOM_TRY
  718.     
  719.         if (_fOtherMenus == kODNULL)
  720.         {
  721.             otherMenus = new OrderedCollection;
  722.             _fOtherMenus = otherMenus;
  723.         }
  724.         info = new ODPrivMenuInfo(menuID, menu,part, beforeID);
  725.         _fOtherMenus->AddLast((ElementType) info);
  726.  
  727.         // if this is the current menu bar, we should also tell the Menu Manager
  728.         TempODMenuBar currentMenuBar = _fSession->GetWindowState(ev)->AcquireCurrentMenuBar(ev);
  729.         if (ODObjectsAreEqual(ev, currentMenuBar, somSelf))
  730.         {
  731.             ::InsertMenu(menu, beforeID);
  732.             ::InvalMenuBar();
  733.         }
  734.  
  735.     SOM_CATCH_ALL
  736.  
  737.         ODDeleteObject(otherMenus);
  738.         ODDeleteObject(info);
  739.  
  740.     SOM_ENDTRY    
  741. }
  742.  
  743. SOM_Scope void  SOMLINK ODMenuBarRemoveMenu(ODMenuBar *somSelf, Environment *ev,
  744.         ODMenuID menu)
  745. {
  746.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  747.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarRemoveMenu");
  748.  
  749.     ODPrivMenuInfo* foundMenu = kODNULL;
  750.     
  751.     SOM_TRY
  752.     
  753.         if (_fOtherMenus)
  754.         {
  755.             OrderedCollectionIterator iter(_fOtherMenus);
  756.             for (ODPrivMenuInfo* menuInfo = (ODPrivMenuInfo*) iter.First();
  757.                 iter.IsNotComplete();
  758.                 menuInfo = (ODPrivMenuInfo*) iter.Next())
  759.             {
  760.                 if (menuInfo->fMenuID == menu)
  761.                 {
  762.                     foundMenu = menuInfo;
  763.                     break;
  764.                 }
  765.             }
  766.             if (foundMenu)
  767.             {
  768.                 _fOtherMenus->Remove((ElementType) foundMenu);
  769.                 
  770.                 // if this is the current menu bar, we should also tell the Menu Manager
  771.                 TempODMenuBar currentMenuBar = _fSession->GetWindowState(ev)->AcquireCurrentMenuBar(ev);
  772.                 if (ODObjectsAreEqual(ev, currentMenuBar, somSelf))
  773.                 {
  774.                     ::DeleteMenu(menu);
  775.                     ::InvalMenuBar();
  776.                 }
  777.             }
  778.             ODDeleteObject(foundMenu);
  779.         }
  780.  
  781.     SOM_CATCH_ALL
  782.     SOM_ENDTRY    
  783. }
  784.  
  785. SOM_Scope ODPlatformMenu  SOMLINK ODMenuBarGetMenu(ODMenuBar *somSelf, Environment *ev,
  786.         ODMenuID menu)
  787. {
  788.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  789.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarGetMenu");
  790.  
  791.     ODPlatformMenu platformMenu = kODNULL;
  792.     
  793.     SOM_TRY
  794.     
  795.     if (_fOtherMenus)
  796.     {
  797.         OrderedCollectionIterator iter(_fOtherMenus);
  798.         for (ODPrivMenuInfo* menuInfo = (ODPrivMenuInfo*) iter.First();
  799.             iter.IsNotComplete();
  800.             menuInfo = (ODPrivMenuInfo*) iter.Next())
  801.         {
  802.             if (menuInfo->fMenuID == menu)
  803.             {
  804.                 platformMenu = menuInfo->fMenu;
  805.                 break;
  806.             }
  807.         }
  808.     }
  809.     // In case it's in the system menus:
  810.     if (platformMenu == kODNULL)
  811.         platformMenu = GetMenuHandle(menu);
  812.  
  813.     SOM_CATCH_ALL
  814.     SOM_ENDTRY    
  815.  
  816.     return platformMenu;
  817. }
  818.  
  819. SOM_Scope ODBoolean  SOMLINK ODMenuBarIsValid(ODMenuBar *somSelf, Environment *ev)
  820. {
  821.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  822.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarIsValid");
  823.     
  824.     ODBoolean isValid = kODFalse;
  825.     
  826.     SOM_TRY
  827.  
  828.         ODMenuBar* baseMenuBar = _fSession->GetWindowState(ev)->AcquireBaseMenuBar(ev); 
  829.         if (baseMenuBar)
  830.             isValid = _fGeneration == baseMenuBar->GetGeneration(ev);
  831.         baseMenuBar->Release(ev);
  832.         
  833.     SOM_CATCH_ALL
  834.     SOM_ENDTRY
  835.     
  836.     return isValid;
  837. }
  838.  
  839.  
  840. SOM_Scope void  SOMLINK ODMenuBarSetGeneration(ODMenuBar *somSelf, Environment *ev,
  841.         ODULong generation)
  842. {
  843.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  844.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarSetGeneration");
  845.  
  846.     _fGeneration = generation;
  847. }
  848.  
  849.  
  850. SOM_Scope ODULong  SOMLINK ODMenuBarGetGeneration(ODMenuBar *somSelf, Environment *ev)
  851. {
  852.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  853.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarGetGeneration");
  854.  
  855.     return _fGeneration;
  856. }
  857.  
  858. SOM_Scope ODMenuBar*  SOMLINK ODMenuBarCopy(ODMenuBar *somSelf, Environment *ev)
  859. {
  860.     ODMenuBarData *somThis = ODMenuBarGetData(somSelf);
  861.     ODMenuBarMethodDebug("ODMenuBar","ODMenuBarCopy");
  862.  
  863.     // Needs work, obviously!
  864.  
  865.     ODMenuBar* copy = kODNULL; ODVolatile(copy);
  866.     
  867.     SOM_TRY
  868.     
  869.         copy = new ODMenuBar();
  870.         THROW_IF_NULL(copy); // "new" does not THROW for SOM objects
  871.         copy->InitMenuBar(ev, _fSession,_fSystemMenus);
  872.     
  873.         if (_fOtherMenus)
  874.         {
  875.             OrderedCollectionIterator iter(_fOtherMenus);
  876.             for (ODPrivMenuInfo* menu = (ODPrivMenuInfo*) iter.First();
  877.                 iter.IsNotComplete();
  878.                 menu = (ODPrivMenuInfo*) iter.Next())
  879.             {
  880.                 if (menu->fPosition == 0)
  881.                     copy->AddMenuLast(ev, menu->fMenuID, menu->fMenu, menu->fPart);
  882.                 else if (menu->fPosition == hierMenu)
  883.                     copy->AddSubMenu(ev, menu->fMenuID, menu->fMenu, menu->fPart);
  884.                 else 
  885.                     copy->AddMenuBefore(ev, menu->fMenuID, menu->fMenu, 
  886.                                         menu->fPart, menu->fPosition);
  887.             }
  888.         if (_fCommandTable) //!!! eeewh!!!
  889.             // copy->fCommandTable = _fCommandTable->Copy();
  890.             copy->SetCommandTable(ev, _fCommandTable->Copy() );    // <eeh> was somSelf->SetCommandTable
  891.         }
  892.         copy->SetGeneration(ev, _fGeneration);
  893.  
  894.     SOM_CATCH_ALL
  895.         
  896.         ODDeleteObject(copy);
  897.         
  898.     SOM_ENDTRY
  899.             
  900.     return copy;
  901. }
  902.